iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
0
Modern Web

今晚,我想來點Blazor系列 第 20

Day 20:Javascript interop

  • 分享至 

  • xImage
  •  

雖然在一開始我們有提到Blazor可以不用任何一行Javascript,就可以完成一個SPA應用程式,但某些情況還是需要依賴Javascript比較容易做到:

  • 使用Web Storage
  • 前端許多好用的Javascript library
  • ...

因此這一篇我們來學習如何在Blazor使用Javascript,這一篇我們一樣用Todolist來做一個範例,之前我們在刪除Todo Item的時候,按刪除後是直接刪掉的,這一篇我們加個confirm,詢問user是否真的要刪除。

Todolist可看這篇

現在我們父元件Todolist有DeletCallback的方法,Todo這個子元件裡面有刪除的onclick方法,那應該要在父元件還是子元件中實作javascript的confirm程式碼呢?

答案是在子元件寫confirm喔,當user按刪除後會執行DeleteItem.InvokeAsync(ItemIndex);來傳ItemIndex給父元件,所以在執行這個傳值動作前,我們先確認user是否要刪除,是的話再進行Invoke動作。

來看一下實際上要怎麼寫吧!
首先在Todo內注入IJSRuntime

@inject IJSRuntime js

接下來修改Delete方法,在這邊IJSRuntime介面有兩個api可以使用:

  • InvokeVoidAsync:執行的程式沒有回傳值,例如Console.log
  • InvokeAsync<T>:要執行的程式有回傳值,可以將回傳的型別寫在<T>
private async Task Delete()
{
    bool result = await js.InvokeAsync<bool>("confirm", $"確定要刪除{ItemName}?");
    if (result)
    {
        await DeleteItem.InvokeAsync(ItemIndex);
    }
}
  • 由於我們需要接收user執行confirm的回傳值,因此使用InvokeAsync<bool>,接收user confirm結果。
  • 結果為true的話,再執行DeleteItem.InvokeAsync(ItemIndex);。
  • 由於js.InvokeAsync使用非同步,所以也將Delete改為非同步方法。

美化一下

使用javascript原生的confirm,雖然能達到我們要的功能,但樣式稍微陽春了點。

在這個龐大且成熟的Javascript生態系,已經有許多好看又好用的套件,例如Jquey-confurm、SweetAlert等等,接下來我們就試著將上述範例套用SweetAlert吧!

首先因為SweetAlert的confirm程式碼較長,我們另外拉一個js到wwwroot下,程式碼會比較好閱讀

  1. 在wwwroot -> 新增scripts資料夾 → 加入一個helper.js檔
  2. 在wwwroot/index.html加入sweet alert 2的cdn還有剛剛新增的helper.js
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
  1. 新增一個funtion,這邊先叫做SweetConfirm。
function SweetConfirm(title, msg) {
    return new Promise((resolve) => {
        Swal.fire({
            title: title,
            text: msg,
            icon: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#3085d6',
            cancelButtonColor: '#d33',
            confirmButtonText: '刪除'
        }).then((result) => {
            if (result.isConfirmed) {
                result.value ? resolve(true) : resolve(false);
            }
        });
    });
}

因為SweetAlert的Swal.fire會回傳Promise,因此用Promise接收confirm結果再回傳

Todo子元件的Delete方法則改成如下:

private async Task Delete()
{
    bool result = await js.InvokeAsync<bool>("SweetConfirm", "Delete", $"確定要刪除{ItemName}?");
    if (result)
    {
        await DeleteItem.InvokeAsync(ItemIndex);
    }
}


上一篇
Day 19:元件的事件處理
下一篇
Day 21:表單
系列文
今晚,我想來點Blazor30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言